OCt 29, 2025·PCBTime of FlightDistance SensorFusion 360
Consider what my final project needs, I decided to add another PCB note here.
This week is about make a distance sensor that measures, well, distance, and hopefully could distance the change on a display.
The sensor I'm getting is VL53L1X. I like this sensor as it had marked down which pin is which.(After some homework on how this sensor works. I reached the conclusion I only needed four pins to make it work: VDD, GND, SDA, SCL)
It comes with a protective cover, needs to remove it before use.VL53L1X (Pololu).All the pinouts are listed: VDD, VINN, GND, SDA, SCL, XSHUT, GPIO1Unlike before, this time I'm using a more powerful microprocessor XIAO ESP32S3. I'm replacing the old SAMD 21 because it lacks the wifi function, which I will be using at a later stage.
As time goes, the pinlist is not that intimidating anymoreOnly four pins needs to be connected: VIN, GND, SCL, SDA
VL53L1X Pin Overview
On the VL53L1X there are six pins: VIN, GND,
SCL, SDA, GPIO, and XSHUT.
It can be a bit overwhelming if you’ve never seen these before, so I looked them up and
summarized what each one does:
VIN
Power input, usually 3.3V or 5V.
GND
Ground reference – must be connected to the microcontroller’s GND.
SCL
I²C clock line – connect to the microcontroller’s SCL pin.
The microcontroller controls the clock pulses on this line.
SDA
I²C data line – connect to the microcontroller’s SDA pin.
All data (commands and readings) flows through this line.
Together, SCL and SDA form the entire I²C communication interface.
GPIO
A general-purpose output from the sensor. This pin is optional and can be used, for example, as an interrupt output.
XSHUT
Shutdown pin (active-low hardware reset).
Pull LOW → the sensor shuts down.
Pull HIGH (3.3V) → the sensor wakes up.
Also added a 4 pin header for a displayOne of the easist connection. Doesn't need 0Ω resistor.😄Something unexpected happened in the board milling. The trace were too shallow, or none at all. Anthony said this could etiher be because I did not screw the drill tight enough, or I did not paste the board on the tabletop properly. I decided to check both and redo the board.The second it was slightly better, but still not quite there yet....
Trying to savage a used board. One thing to notice is my milling time is significant longer than others. So I got rid of the text part(that has no practical value) in exchange for a faster milling.
Finally a board that works. Checked with multimeter and confirmed that.However, because of my carelessness, or just simply shaking hands...I destroyed a perfectly working board. I had to make another one....
One library needs to be installed before the real programing - VL53L1X.h
Even with simple wire connection, I run into an unexpcted problem. I wrote a program that scan the address on the sensor and the result came back shocked me. It seems the system detected 120+ devices.
How can this be? I did some research, and even though I could not be sure, but it is based on this theory that I eventually solved the issue. It seems the wire I used was too long, which means the HIGH and LOW are no longer really HIGH and LOW but somewhere floating, creating a lot of noise. So I changed to short wires, and problem gone. Now it's showing only one device! (At the address of 0x29)
Now I have one device found, not 120+
Arduino / C++ Scanning for device (Debug with ChatGPT)
#include<Wire.h>// Change these if you’re on a board where you can re-map I2C pins (ESP32, etc.)#ifndefSDA#defineSDA-1#endif#ifndefSCL#defineSCL-1#endifstaticconstuint8_tVL53_ADDR = 0x29;
// ---- Low-level I2C helpers for VL53L1X register access ----// VL53L1X uses 16-bit register addresses.boolwriteReg16(uint8_t addr, uint16_t reg, uint8_t value) {
Wire.beginTransmission(addr);
Wire.write((uint8_t)(reg >> 8));
Wire.write((uint8_t)(reg & 0xFF));
Wire.write(value);
return (Wire.endTransmission() == 0);
}
boolreadReg8(uint8_t addr, uint16_t reg, uint8_t &out) {
Wire.beginTransmission(addr);
Wire.write((uint8_t)(reg >> 8));
Wire.write((uint8_t)(reg & 0xFF));
if (Wire.endTransmission(false) != 0) {
returnfalse;
}
int n = Wire.requestFrom((int)addr, 1);
if (n != 1) returnfalse;
out = Wire.read();
returntrue;
}
voidi2cScan() {
Serial.println("=== I2C scan ===");
int found = 0;
for (uint8_t a = 1; a < 127; a++) {
Wire.beginTransmission(a);
uint8_t err = Wire.endTransmission();
if (err == 0) {
Serial.print(" Found device at 0x");
if (a < 16) Serial.print("0");
Serial.println(a, HEX);
found++;
}
}
Serial.print("Total I2C devices: ");
Serial.println(found);
Serial.println("=== I2C scan end ===\n");
}
voidsetup() {
Serial.begin(115200);
delay(800);
Serial.println("\nVL53L1X I2C + ID Test\n");
Wire.begin();
Wire.setClock(400000);
i2cScan();
Serial.println("Checking for device at 0x29...");
Wire.beginTransmission(VL53_ADDR);
uint8_t err = Wire.endTransmission();
Serial.print(" endTransmission returned: ");
Serial.println(err);
if (err != 0) {
Serial.println("\n❌ No ACK from 0x29.\n");
return;
}
Serial.println("✅ 0x29 ACKed.\n");
Serial.println("Reading Model ID (reg 0x010F)...");
uint8_t modelId = 0;
bool ok = readReg8(VL53_ADDR, 0x010F, modelId);
if (!ok) {
Serial.println("❌ Failed to read Model ID.");
return;
}
Serial.print("✅ Model ID read: 0x");
Serial.println(modelId, HEX);
}
voidloop() {
delay(3000);
i2cScan();
}
Since the connection is very simple, and I had a major setback on the soldering the board. I decided to just connect the two electronics with simple wire and write program to see if this thing works. It went really surprisingly smooth. It worked, even though with a few caveats that I will mention later.
The intial program had a refresh rate or loop delay set too high. So I lowered it quite a bit for myself to track it.
Now that I know for sure the sensor works and I understand the pins right. I milled the board using Bantam in the Lab.Board soldering complete
Initial Observations (Distance Sensor Test)
1) Readings were not perfectly constant (mm-level jitter)
Even though the sensor was placed on a stable table and measured the distance to the room ceiling,
the returned values were not identical each time.
The readings were largely consistent, but each measurement still varied by a few millimeters.
This suggests the sensor has a small but noticeable measurement error / noise under real conditions.
2) “Zero” was reported before physical contact
When I moved my hand close to the sensor, it did not need to physically touch the sensor for the reading to become zero.
I could get a reading of 0 even when my palm was still approximately 3–4 cm away.
This suggests there may be a minimum measurable range or clamping behavior.
My hypothesis: below a certain threshold distance, the sensor reports 0 (no negative values).
In other words, the displayed value may behave like:
max(0, real_distance - threshold)